package com.cloudcentral.config;

import com.cloudcentral.exception.FailureException;
import com.cloudcentral.service.UserService;
import com.cloudcentral.util.VerifyUtils;
import org.redisson.api.RedissonClient;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import static com.cloudcentral.util.Utils.errorMessage;

/**
 * Create by Administrator
 * 2023/11/10 10:58
 */
public class SMSAuthenticationProvider implements AuthenticationProvider {
  private final UserService userDetailService;
  private final RedissonClient redissonClient;

  public SMSAuthenticationProvider(UserService userDetailService, RedissonClient redissonClient) {
    this.userDetailService = userDetailService;
    this.redissonClient = redissonClient;
  }

  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    try {
      SMSAuthenticationToken authenticationToken = (SMSAuthenticationToken) authentication;
      String principal = authentication.getPrincipal().toString();// 获取凭证也就是用户的手机号
      String credentials = authentication.getCredentials().toString();// 获取输入的验证码
      VerifyUtils.code(redissonClient, principal, credentials);
      redissonClient.getBucket(principal).delete();// 删除验证码
      UserDetails userDetails = userDetailService.loadUserByUsername(principal);
      SMSAuthenticationToken authenticationResult = new SMSAuthenticationToken(principal, userDetails, userDetails.getAuthorities());
      authenticationResult.setDetails(authenticationToken.getDetails());
      return authenticationResult;
    } catch (FailureException e) {
      throw new BadCredentialsException(errorMessage(e));
    } catch (UsernameNotFoundException e) {
      throw new InternalAuthenticationServiceException("用户尚未注册");
    }
  }

  @Override
  public boolean supports(Class<?> authentication) {
    return SMSAuthenticationToken.class.isAssignableFrom(authentication);
  }
}
